using System;
using System.IO;
using System.Diagnostics;
using System.Text;
using System.Collections.Generic;
using System.Collections.Specialized;
using My.IdlConverter.Core;
using My.IdlConverter.Core.Util;
using My.IdlConverter.Core.Graphics;
using My.IdlConverter.Core.Output;
using My.IdlConverter.Core.Parsers;
using My.IdlConverter.Core.Producers;
using My.IdlConverter.Core.Cfg;
using My.IdlConverter.Core.Filters;

namespace My.IdlConverter.Com
{
    public class ComIdlExporter : ExportBase
    {
        private StringCollection _filePathNamesBuffer = new StringCollection();
        private IList<string> _exportedInterfaces = new List<string>();

        public ComIdlExporter(string targetPathName)
            :base(targetPathName)
        {
        }

        public override void Export()
        {
            if (!Directory.Exists(Configuration.InterfaceFolder))
                throw new IOException("The interface folder is not existent.");

            IStreamWriter<String> writer = new TextStreamWriter<String>(TargetPath);
            StringBuilder buffer = new StringBuilder();
            buffer.AppendLine("import \"oaidl.idl\";");
            buffer.AppendLine("import \"ocidl.idl\";");
            buffer.AppendLine();

            IList<Interface> allInterfaces = Component.Interfaces;
            foreach (Interface nextInterface in allInterfaces)
            {
                buffer.AppendLine("interface "+ InterfaceModifier.GetName(nextInterface.Name) + ";");
            }

            buffer.AppendLine();
            buffer.Append(ComComponentRegistar.Declaration);
            buffer.AppendLine();

            ExportEventArgs args = new ExportEventArgs();

            IProducer<Interface> producer = new ComInterfaceProducer();
            IParser parser = new InterfaceParser();
            ITwiceProcessor<Interface> twiceProcessor = new ComTwiceProcessor();

            StringCollection files = IOHelper.GetCppHeaderFiles(Configuration.InterfaceFolder, Delegators.FilterInterfaceFun, false);
            foreach (string nextFile in files)
            {
                parser.OverloadCollision =MethodCollisionManager.Instance.GetCollision<ComOverloadMethodCollision>();
                Interface interfaceObj = parser.Parse(nextFile) as Interface;
                producer = new ComInterfaceProducer();
                producer.Consumer = interfaceObj;
                string idlString = producer.Produce();
                buffer.Append(twiceProcessor.Process(interfaceObj, idlString, parser.OverloadCollision));
                buffer.AppendLine();

                args.FileName = nextFile;
                FireExportEvent(args);
            }

            //library
            ComLibraryTemplate libTemplate = new ComMyFitTemplateLibrary(ClassForest.Instance);
            buffer.Append(libTemplate.New().ToString());

            writer.Write(buffer.ToString());
        }

    }
}
